package com.wanyang.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import com.github.pagehelper.PageHelper;
import com.wanyang.aliyun.dto.ImageTaskDTO;
import com.wanyang.aliyun.dto.TextTaskDTO;
import com.wanyang.aliyun.service.AliyunContentScanService;
import com.wanyang.bo.MemberBO;
import com.wanyang.dao.CommonDao;
import com.wanyang.dao.MemberDao;
import com.wanyang.dos.GoldRecordDO;
import com.wanyang.dos.GoldRecordDOExample;
import com.wanyang.dos.MemberDO;
import com.wanyang.dos.MemberDOExample;
import com.wanyang.dto.PageDTO;
import com.wanyang.exception.ApiException;
import com.wanyang.mapper.GoldRecordDOMapper;
import com.wanyang.mapper.MemberDOMapper;
import com.wanyang.utils.DateUtil;
import com.wanyang.utils.ShareCodeUtil;
import com.wanyang.vo.MemberVO;
import com.wanyang.vo.PublisherVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
public class MemberServiceImpl implements MemberService {
    @Resource
    private MemberDOMapper memberDOMapper;

    @Resource
    private CommonDao commonDao;

    @Autowired
    private FollowerService followerService;

    @Autowired
    private LevelExperienceService levelExperienceService;

    @Resource
    private GoldRecordDOMapper goldRecordDOMapper;

    @Resource
    private MemberDao memberDao;

    @Override
    public MemberDO getModel(Integer memberId) {
        if (memberId == null)
            return null;
        return memberDOMapper.selectByPrimaryKey(memberId);
    }

    @Override
    public MemberBO getMemberBO(Integer memberId) {
        return MemberBO.newInstance(getModel(memberId));
    }

    @Override
    public MemberDO getModel(String mobile) {
        MemberDOExample example = new MemberDOExample();
        example.createCriteria().andMobileEqualTo(mobile);
        return memberDOMapper.selectOneByExample(example);
    }

    @Override
    @Transactional
    public MemberDO register(String mobile, String shareCode) {
        MemberDO exist = getModel(mobile);
        if (exist != null) {
            return exist;
        }


        MemberDO memberDO = new MemberDO();
        memberDO.setInviterId(StringUtils.isNotBlank(shareCode) ? ShareCodeUtil.codeToId(shareCode) : null);
        memberDO.setMobile(mobile);
        memberDO.setNickname(mobile);
        memberDO.setAreaId(Constants.defaultAreaId);
        memberDO.setGold(BigDecimal.ZERO);
        memberDO.setLevel(1);
        memberDO.setExperience(0);
        memberDO.setTotalFollow(0);
        memberDO.setTotalPost(0);
        memberDO.setTotalFans(0);
        memberDO.setIsDelete(false);
        memberDO.setIsBan(false);
        memberDO.setCreateTime(DateUtil.currentUnixTime());

        memberDOMapper.insertSelective(memberDO);

        Integer memberId = commonDao.mysqlLastId();

        MemberDO update = new MemberDO();
        update.setId(memberId);
        update.setShareCode(ShareCodeUtil.toSerialCode(memberId));

        memberDOMapper.updateByPrimaryKeySelective(update);

        memberDO.setShareCode(update.getShareCode());
        memberDO.setId(memberId);

        // TODO 计算邀请人金币收入

        if (StringUtils.isNotBlank(shareCode)) {
            GoldRecordDO goldRecordDO = new GoldRecordDO();
            goldRecordDO.setGold(new BigDecimal(10));
            goldRecordDO.setCreateTime(DateUtil.currentUnixTime());
            goldRecordDO.setRemark("好友邀请");
            goldRecordDO.setMemberId(Long.valueOf(ShareCodeUtil.codeToId(shareCode)).intValue());
            goldRecordDOMapper.insertSelective(goldRecordDO);
        }

        return memberDO;
    }

    @Override
    public PublisherVO getPublisherVO(Integer publisherId) {
        MemberDO publisher;
        PublisherVO publisherVO = BeanUtil.copyProperties(publisher = this.getModel(publisherId), PublisherVO.class);
        publisherVO.setMemberId(publisher.getId());

        MemberDO currentMember = UserContext.get();

        if (currentMember != null) {
            boolean isSelf = publisherId.equals(currentMember.getId());
            publisherVO.setSelf(isSelf);

            if (!isSelf) {
                boolean isFollowed = followerService.isFollowed(currentMember.getId(), publisherId);
                publisherVO.setFollow(isFollowed);

            }

        }

        return publisherVO;
    }

    private static final String[] allowedUpdateKeys = {"nickname", "personalizedSignature", "sex", "avatar", "backgroundImg"};
    private static final String[] allowedSexValue = {"1", "2"};

    @Autowired
    private AliyunContentScanService aliyunContentScanService;

    @Override
    public MemberDO updateInfo(Integer memberId, String key, String value) {
        if (ArrayUtil.contains(allowedUpdateKeys, key)) {
            MemberDO memberDO = new MemberDO();
            memberDO.setId(memberId);

            if (allowedUpdateKeys[2].equals(key)) {
                if (!ArrayUtil.contains(allowedSexValue, value)) {
                    throw new ApiException("无效的value");
                }
                memberDO.setSex(Integer.parseInt(value));

            } else {
                try {
                    Class c = memberDO.getClass();
                    Field f = c.getDeclaredField(key);
                    f.setAccessible(true);
                    f.set(memberDO, value);
                } catch (Exception e) {
                    throw new ApiException(e.getMessage());
                }
            }

            // 用户名，个性签名可能需要审核
            if (StringUtils.isNotEmpty(memberDO.getNickname())) {
                TextTaskDTO textTaskDTO = new TextTaskDTO(UUID.randomUUID().toString(), memberDO.getNickname());
                aliyunContentScanService.syncTextScan(Collections.singletonList(textTaskDTO), ((dataId, pass) -> {
                    if (!pass) {
                        // TODO 违规后处理
                        throw new ApiException("用户名违规");
                    }
                }));
            }

            if (StringUtils.isNotEmpty(memberDO.getPersonalizedSignature())) {
                TextTaskDTO textTaskDTO = new TextTaskDTO(UUID.randomUUID().toString(), memberDO.getPersonalizedSignature());
                aliyunContentScanService.syncTextScan(Collections.singletonList(textTaskDTO), ((dataId, pass) -> {
                    if (!pass) {
                        throw new ApiException("签名违规");
                    }
                }));
            }

            if (StringUtils.isNotEmpty(memberDO.getBackgroundImg())) {
                ImageTaskDTO imageTaskDTO = new ImageTaskDTO();
                imageTaskDTO.setDataId(UUID.randomUUID().toString());
                imageTaskDTO.setTime(new Date());
                imageTaskDTO.setUrl(memberDO.getBackgroundImg());

                aliyunContentScanService.imageSyncScan(Collections.singletonList(imageTaskDTO), ((dataId, pass) -> {
                    if (!pass) {
                        throw new ApiException("图片违规");
                    }
                }));
            }

            if (StringUtils.isNotEmpty(memberDO.getAvatar())) {
                ImageTaskDTO imageTaskDTO = new ImageTaskDTO();
                imageTaskDTO.setDataId(UUID.randomUUID().toString());
                imageTaskDTO.setTime(new Date());
                imageTaskDTO.setUrl(memberDO.getAvatar());

                aliyunContentScanService.imageSyncScan(Collections.singletonList(imageTaskDTO), ((dataId, pass) -> {
                    if (!pass) {
                        throw new ApiException("图片违规");
                    }
                }));
            }

            memberDOMapper.updateByPrimaryKeySelective(memberDO);

        } else {
            throw new ApiException("无效的key");
        }

        return this.getModel(memberId);
    }

    @Override
    public MemberVO getVO(Integer memberId) {
        MemberDO model = getModel(memberId);
        MemberVO memberVO = new MemberVO();
        BeanUtils.copyProperties(model, memberVO);

        if (memberVO.getLevel() == 1) {
            memberVO.setCurrentExperience(memberVO.getExperience());
        } else {
            BigDecimal levelExperience = levelExperienceService.getLevelExperience(memberVO.getLevel());
            memberVO.setCurrentExperience(memberVO.getExperience() - levelExperience.intValue());
        }


        return memberVO;
    }

    @Override
    public List<GoldRecordDO> getGoldRecord(Integer memberId, PageDTO pageDTO) {
        GoldRecordDOExample example = new GoldRecordDOExample();
        example.createCriteria().andMemberIdEqualTo(memberId);
        example.setOrderByClause("create_time desc");
        PageHelper.startPage(pageDTO);
        List<GoldRecordDO> goldRecordDOs = goldRecordDOMapper.selectByExample(example);
        return goldRecordDOs;
    }

    @Override
    public boolean operateGold(Integer memberId, BigDecimal gold) {
        return memberDao.operateGold(memberId, BigDecimal.ZERO.subtract(gold)) > 0;
    }
}
